MENUS ------------------------------------------------------------------- The TEGL WINDOWS TOOLKIT II provides an extensive number of menu functions. You can create bar menus and pull-down (or up) menus. The basic item in a TEGL menu is the Option Menu. These are accessed through a pointer, an optionmptr. Creating a bar menu require a few steps. First we have to create some option menus to attach to the bar menu. To do this use the function createoptionmenu. It is declared as follows: optionmptr createoptionmenu(fontptr fonttype); fonttype is the font to use when displaying the menu selections. The optionmptr that is returned is used to add selections to the option menu and is finally attached to a bar menu (or mouse click area). After the option menu has been created use defineoptions to add selections to the menu. void defineoptions(optionmptr om, char *entrystr, unsigned char active, callproc event); The first parameter, om, is the optionmptr that must have been created with defineoptions. entrystr is the text that will be displayed for the menu selection. Active sets whether the menu item can be selected, if TRUE then it can be selected, when FALSE it cannot and will appear in a lighter shade than the other menu selections. Event is the event-handler that will be called when the menu selection is clicked on. The '-' (hyphen) is used to place a separator line between options, it will appear as continuous line. When adding a separator the active parameter should alway be FALSE and the event should be nilunitproc which is a place holder event-handler that just returns. Note that menu selections (either bar or option menu) can have the tilde character '~' placed around one of the characters in the text for the menu selection. When this item is displayed the character will be underscored and the corresponding key will be trapped for. The next step is create a bar menu that the option menu('s) can be attached to. To do this we use createbarmenu. void createbarmenu(unsigned x, unsigned y, unsigned length); x, y is the postion (in absolute screen coordinates) where the bar menu is to be placed. length is the length of the menu in pixels. The font that is used to display the bar menu is the current font, if you want to use a specific font use setteglfont before calling createbarmenu. Hint: A bar menu is really just a long narrow frame, and like any frame you change certain characteristics. Sometimes it might be useful to save the stackptr right after creating a bar menu. When the bar menu has been created the option menus are attaced to it using outbaroption. void outbaroption(char *entrystr, optionmptr om); The entrystr is the bar menu selection and om is the option menu that will appear when the selection is made. The option menu will appear as a drop down or drop up menu depending on where the bar menu is located. Here is a small but complete program example of a bar menu with just one selection. The one selection is an option menu with the entries: 'File' which does nothing, '-' which gives a separator line (for appearance sake, and 'Exit' which will end the program. Note: nilunitproc is an event-handler which does nothing. It can be used as place holder when you are creating the menu interface of program but haven't completed the guts, and it is also used where an event parameter (even one that is never called) is required. BEGINFILE> menu1.c /* -- menu1.c */ #include "teglsys.h" unsigned exitoption(imagestkptr ifs, msclickptr ms) { abortexit(""); return 0; } optionmptr omfile; void main(void) { easytegl(); easyout(); omfile = createoptionmenu(f8x12bol); defineoptions(omfile," ~O~pen ",TRUE,nilunitproc); defineoptions(omfile,"-",TRUE,nilunitproc); defineoptions(omfile," E~x~it ",TRUE,exitoption); setteglfont(f8x12bol); createbarmenu(0,0,getmaxx()); outbaroption(" ~F~ile ",omfile); teglsupervisor(); } ENDFILE> We can nest menus arbitrarily deep. To do this we use void defineoptionssub(optionmptr om, char *entrystr, char active, optionmptr om2); This simply attaches an option menu selection that is another option menu as opposed to an event-handler. As you can see the last parameter is an optionmptr. This example adds two levels of menus, they don't do anything (that's up to you) but it illustrates the use. BEGINFILE> menu2.c /* -- menu2.c */ #include "teglsys.h" unsigned exitoption(imagestkptr ifs, msclickptr ms) { abortexit(""); return 0; } fontptr menufont; /* -- by setting the font into a pointer we can */ /* -- more easily change our selection of the font */ /* -- to use. */ optionmptr omfile; optionmptr omfile2; optionmptr omfile3; void main(void) { easytegl(); easyout(); menufont = f8x12bol; omfile3 = createoptionmenu(menufont); defineoptions(omfile3," ~T~o floppy ",TRUE,nilunitproc); defineoptions(omfile3," ~F~rom floppy ",TRUE,nilunitproc); omfile2 = createoptionmenu(menufont); defineoptions(omfile2," ~F~ormat ",FALSE,nilunitproc); defineoptions(omfile2," ~D~elete ",FALSE,nilunitproc); defineoptionssub(omfile2," ~C~opy ",TRUE,omfile3); omfile = createoptionmenu(menufont); defineoptions(omfile," ~O~pen ",TRUE,nilunitproc); defineoptionssub(omfile," ~D~os functions ",TRUE,omfile2); defineoptions(omfile,"-",FALSE,nilunitproc); defineoptions(omfile," E~x~it ",TRUE,exitoption); setteglfont(menufont); createbarmenu(0,0,getmaxx()); outbaroption(" ~F~ile ",omfile); teglsupervisor(); } ENDFILE> Some people really get carried away when it comes to making menus, generally we don't recommend really long menus and try to keep them under several hundred items. This example just shows what happens when an excessive number of menu selections is added to an option menu. BEGINFILE> menu3.c /* -- menu3.c */ #include "teglsys.h" char *itos(int i) { static char s[25]; itoa(i,s,10); return s; } unsigned exitoption( imagestkptr ifs, msclickptr ms) { abortexit(""); return 0; } optionmptr omfile; optionmptr omopen; int i; void main(void) { char fn[20]; easytegl(); easyout(); omopen = createoptionmenu(f8x8bold); for (i = 1; i <= 50; i++) { strcpy(fn," file "); strcat(fn,itos(i)); defineoptions(omopen,fn,random(2) == 1,nilunitproc); } omfile = createoptionmenu(f8x12bol); defineoptionssub(omfile," ~O~pen ",TRUE,omopen); defineoptions(omfile,"-",FALSE,nilunitproc); defineoptions(omfile," E~x~it ",TRUE,exitoption); setteglfont(&f8x12bol); createbarmenu(0,0,getmaxx()); outbaroption(" ~F~ile ",omfile); teglsupervisor(); } ENDFILE> A useful item to have in a menu is a check-marked item. These are usually boolean flags to indicate some sort of preference. There is a special option menu item for this: void defineoptionscheck(optionmptr om, char *entrystr, unsigned char active, callproc event, char *chkmark); The big distinction here is that we pass a variable to the routine so that when it is selected the variable will be toggled. After the variable is updated then the event-handler is called, presumably to do some processing if required. Our example doesn't do this, but you probably get the idea. When the item is TRUE then a check mark is displayed next to it, when FALSE no check mark. BEGINFILE> menu4.c /* -- menu4.c */ #include "teglsys.h" unsigned exitoption(imagestkptr ifs, msclickptr ms) { abortexit(""); return 0; } fontptr menufont; optionmptr omfile; char fullpath = TRUE; void main(void) { easytegl(); easyout(); menufont = f8x12bol; omfile = createoptionmenu(menufont); defineoptions(omfile," ~O~pen ",TRUE,nilunitproc); defineoptionscheck(omfile," ~F~ull path ",TRUE,nilunitproc,&fullpath); defineoptions(omfile,"-",FALSE,nilunitproc); defineoptions(omfile," E~x~it ",TRUE,exitoption); setteglfont(menufont); createbarmenu(0,0,getmaxx()); outbaroption(" ~F~ile ",omfile); teglsupervisor(); } ENDFILE> Another useful kind of check mark is one where there can be a limited number of choices but more than just a boolean toggle. void defineoptionsradio(optionmptr om, char *entrystr, char active, callproc event, unsigned entryradiovalue, unsigned *radiovar); Here the distinction is radiovar is an unsigned, so you could have a lot of choices but generally this kind of item is used for 2 to 5 or perhaps a few more. Each item that uses the same radiovar must have a different entryradiovalue. As with defineoptionscheck the event-handler is called after the variable has been updated. BEGINFILE> menu5.c /* -- menu5.c */ #include "teglsys.h" unsigned exitoption(imagestkptr ifs, msclickptr ms) { abortexit(""); return 0; } fontptr menufont; optionmptr omfile; unsigned sortoption = 1; void main(void) { easytegl(); easyout(); menufont = f8x12bol; omfile = createoptionmenu(menufont); defineoptions(omfile," ~O~pen ",TRUE,nilunitproc); defineoptions(omfile,"-",FALSE,nilunitproc); defineoptionsradio(omfile," ~N~ame ",TRUE,nilunitproc,1,&sortoption); defineoptionsradio(omfile," ~E~xtension ",TRUE,nilunitproc,2,&sortoption); defineoptionsradio(omfile," ~D~ate ",TRUE,nilunitproc,3,&sortoption); defineoptionsradio(omfile," N~o~ne ",TRUE,nilunitproc,4,&sortoption); defineoptions(omfile,"-",FALSE,nilunitproc); defineoptions(omfile," E~x~it ",TRUE,exitoption); setteglfont(menufont); createbarmenu(0,0,getmaxx()); outbaroption(" ~F~ile ",omfile); teglsupervisor(); } ENDFILE> PREFERENCES You can set a number of items to suit your needs or preferences for menus. void sethidesubmenu(char onoff); This sets whether the sub menus should be dropped before the resulting event-handler has returned. The default is for the sub menus to remain visible on the screen (FALSE). If set TRUE then the menus are hidden just as soon as a selection is made. setomdisplaynum(optionmptr om, unsigned num); This sets the limit on how many menu items to display before an option menu sprouts a slider bar. If you don't change it then the menu can be the full size of the screen. See the example program 'menudemo.pas' for a comprehensive look at how a menu system can be set up. ------- END MENUS.TXT